﻿using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebDocDB.DocumentDBManager.Extensions;
using WebDocDB.Managers;

namespace WebDocDB.DocumentDBManager
{
    public class DocumentsManager : IDocumentsManager
    {
        private DocumentClient _client;

        public DocumentsManager(IAccountManager accountManager)
        {
            var accountSettings = accountManager.GetAccountSettings();
            _client = new DocumentClient(new Uri(accountSettings.EndpointUrl), accountSettings.MasterKey,
                   new ConnectionPolicy { ConnectionMode = accountSettings.ConnectionMode, ConnectionProtocol = accountSettings.Protocol });
        }

        public async Task<List<WebDocDB.Models.Document>> GetAllDocuments(string collectionLink)
        {
            FeedResponse<dynamic> documents = await _client.ReadDocumentFeedAsync(collectionLink);

            var docList = new List<WebDocDB.Models.Document>();

            foreach (var doc in documents)
            {
                docList.Add(new WebDocDB.Models.Document() { ID = doc.Id, Link = doc.SelfLink });
            }

            return docList;
        }

        public async Task AddDocument(string collectionLink, string jsonText)
        {
            try
            {
                object document = JsonConvert.DeserializeObject(jsonText);

                var response = await _client.CreateDocumentAsync(collectionLink, document);

            }
            catch (AggregateException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public async Task DeleteDocument(string documentLink)
        {
            try
            {
                var response = await _client.DeleteDocumentAsync(documentLink);                
            }
            catch (AggregateException ae)
            {
                throw ae;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        private async Task<FeedResponse<dynamic>> ExecuteQueryRaw(string collectionLink, string queryText)
        {
            FeedResponse<dynamic> documents = null;

            try
            {
                IDocumentQuery<dynamic> q = _client.CreateDocumentQuery(collectionLink, queryText).AsDocumentQuery();
                documents = await q.ExecuteNextAsync();                
            }
            catch (AggregateException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw e;
            }

            return documents;
        }

        public async Task<string> ExecuteQuery(string collectionLink, string queryText)
        {
            FeedResponse<dynamic> documents = null;

            try
            {
                documents = await ExecuteQueryRaw(collectionLink, queryText);

            }
            catch (AggregateException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw e;
            }

            return documents.ToFormattedJsonString();
            
        }

    }
}
